package com.android.example.record.activity;

import android.content.Intent;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.android.example.record.MainActivity;
import com.android.example.record.R;
import com.android.example.record.adapter.PoiItemAdapter;
import com.android.example.record.databinding.ActivitySelectLocBinding;
import com.android.example.record.utils.Utils;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.Projection;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;

import java.util.ArrayList;
import java.util.List;

public class SelectLocActivity extends AppCompatActivity implements
        BaiduMap.OnMapStatusChangeListener,
        PoiItemAdapter.OnItemClickListener,
        OnGetGeoCoderResultListener {

    private ActivitySelectLocBinding binding;

    private BaiduMap baiduMap;

    private LatLng center;
    private Handler handler;

    private PoiItemAdapter poiItemAdapter;

    private GeoCoder geoCoder = null;

    private static final int S_DEFAULT_RGC_RADIUS = 500;  // 默认逆地理编码半径范围
    private boolean statusChangeByItemClick = false;

    Intent intent;

    double latitude;
    double longitude;
    double newLatitude;
    double newLongitude;
    String loc;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        intent = getIntent();
        latitude = intent.getDoubleExtra("latitude", 39.963175f);
        longitude = intent.getDoubleExtra("longitude", 116.400244f);
        newLatitude = latitude;
        newLongitude = longitude;
        binding = ActivitySelectLocBinding.inflate(getLayoutInflater());
        View view = binding.getRoot();
        super.onCreate(savedInstanceState);
        setContentView(view);

        init();

        binding.cancel.setOnClickListener(this::finish);
        binding.reLocate.setOnClickListener(this::reLocate);
    }

    @Override
    protected void onResume() {
        super.onResume();
        binding.mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        binding.mapView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (null != handler) {
            handler.removeCallbacksAndMessages(null);
        }

        if (null != geoCoder) {
            geoCoder.destroy();
        }

        binding.mapView.onDestroy();
    }

    private void init() {
        initRecyclerView();

        handler = new Handler(this.getMainLooper());

        initMap();
    }

    private void initMap() {
        baiduMap = binding.mapView.getMap();
        if (null == baiduMap) {
            return;
        }


        // View child = binding.mapView.getChildAt(1);
        // if ((child instanceof ImageView || child instanceof ZoomControls)) {
        //     child.setVisibility(View.INVISIBLE); // 隐藏 logo
        // }

        binding.mapView.showZoomControls(false); // 隐藏缩放控件
        // binding.mapView.showScaleControl(false); // 隐藏比例尺

        // 设置初始中心点
        center = new LatLng(newLatitude, newLongitude);
        MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLngZoom(center, 16);
        baiduMap.setMapStatus(mapStatusUpdate);
        baiduMap.setOnMapStatusChangeListener(this);
        baiduMap.setOnMapLoadedCallback(() -> {
            createCenterMarker();
            reverseRequest(center);
        });


    }

    /**
     * 创建地图中心点marker
     */
    private void createCenterMarker() {
        Projection projection = baiduMap.getProjection();
        if (null == projection) {
            return;
        }

        Point point = projection.toScreenLocation(center);
        BitmapDescriptor bitmapDescriptor =
                BitmapDescriptorFactory.fromResource(R.drawable.icon_binding_point);
        if (null == bitmapDescriptor) {
            return;
        }

        MarkerOptions markerOptions = new MarkerOptions()
                .position(center)
                .icon(bitmapDescriptor)
                .flat(false)
                .fixedScreenPosition(point);
        baiduMap.addOverlay(markerOptions);

        bitmapDescriptor.recycle();
    }

    private void initRecyclerView() {

        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(RecyclerView.VERTICAL);
        binding.poiRecyclerView.setLayoutManager(layoutManager);
    }

    /**
     * 逆地理编码请求
     *
     * @param latLng 经纬度
     */
    private void reverseRequest(LatLng latLng) {
        if (null == latLng) {
            return;
        }

        ReverseGeoCodeOption reverseGeoCodeOption = new ReverseGeoCodeOption().location(latLng)
                .newVersion(1) // 建议请求新版数据
                .radius(S_DEFAULT_RGC_RADIUS);

        if (null == geoCoder) {
            geoCoder = GeoCoder.newInstance();
        }

        geoCoder.setOnGetGeoCodeResultListener(this);
        geoCoder.reverseGeoCode(reverseGeoCodeOption);
    }

    @Override
    public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
    }

    @Override
    public void onGetReverseGeoCodeResult(final ReverseGeoCodeResult reverseGeoCodeResult) {
        if (null == reverseGeoCodeResult) {
            return;
        }

        handler.post(() -> updateUI(reverseGeoCodeResult));
    }

    /**
     * 更新UI
     *
     * @param reverseGeoCodeResult 反向地理代码结果
     */
    @SuppressWarnings("SpellCheckingInspection")
    private void updateUI(ReverseGeoCodeResult reverseGeoCodeResult) {
        List<PoiInfo> poiInfos = reverseGeoCodeResult.getPoiList();

        PoiInfo curAddressPoiInfo = new PoiInfo();
        curAddressPoiInfo.address = reverseGeoCodeResult.getAddress();
        curAddressPoiInfo.location = reverseGeoCodeResult.getLocation();

        if (null == poiInfos) {
            poiInfos = new ArrayList<>(2);
        }

        poiInfos.add(0, curAddressPoiInfo);

        if (null == poiItemAdapter) {
            poiItemAdapter = new PoiItemAdapter(poiInfos);
            binding.poiRecyclerView.setAdapter(poiItemAdapter);
            poiItemAdapter.setOnItemClickListener(this);
        } else {
            poiItemAdapter.updateData(poiInfos);
        }
    }

    @Override
    public void onMapStatusChangeStart(MapStatus mapStatus) {
    }

    @Override
    public void onMapStatusChangeStart(MapStatus mapStatus, int i) {
    }

    @Override
    public void onMapStatusChange(MapStatus mapStatus) {
    }

    @Override
    public void onMapStatusChangeFinish(MapStatus mapStatus) {
        LatLng newCenter = mapStatus.target;

        // 如果是点击poi item导致的地图状态更新，则不用做后面的逆地理请求，
        if (statusChangeByItemClick) {
            if (Utils.isLatLngEqual(center, newCenter)) {
                center = newCenter;
            }
            statusChangeByItemClick = false;
            return;
        }

        if (Utils.isLatLngEqual(center, newCenter)) {
            center = newCenter;
            reverseRequest(center);
        }
    }

    @Override
    public void onItemClick(int position, PoiInfo poiInfo) {
        if (null == poiInfo || null == poiInfo.getLocation()) {
            return;
        }

        statusChangeByItemClick = true;
        MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLng(poiInfo.getLocation());
        baiduMap.setMapStatus(mapStatusUpdate);
    }

    @Override
    public void onItemCertain(int position) {
        List<PoiInfo> poiInfoList = poiItemAdapter.poiInfos;
        PoiInfo curPoiInfo = poiInfoList.get(position);
        String poiName = curPoiInfo.getName();
        loc = curPoiInfo.getAddress();
        if (poiName != null) {
            loc = poiName + "\n" + loc;
        } else {
            loc = "" + "\n" + loc;
        }
        newLatitude = curPoiInfo.getLocation().latitude;
        newLongitude = curPoiInfo.getLocation().longitude;

        binding.certain.setOnClickListener(this::sendLocation);
    }

    private void sendLocation(View view) {
        intent = new Intent(this, MainActivity.class);
        intent.putExtra("loc", loc);
        intent.putExtra("lat", newLatitude);
        intent.putExtra("lng", newLongitude);
        startActivity(intent);
        finish();
    }

    private void reLocate(View view) {
        reLocate(latitude, longitude);
    }

    private void reLocate(double latitude, double longitude) {
        LatLng ll = new LatLng(latitude, longitude);
        MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLng(ll);
        baiduMap.animateMapStatus(mapStatusUpdate);
    }

    private void finish(View view) {
        intent = new Intent(this, MainActivity.class);
        intent.putExtra("send", false);
        startActivity(intent);
        finish();
    }
}